﻿using Prism.Commands;
using Prism.Mvvm;
using Prism.Services.Dialogs;
using SIMS.Shared.DTO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using SIMS.Common.RestClient;
using SIMS.Common.Models;
using Newtonsoft.Json;
using SIMS.Shared.Models;

namespace SIMS.ScoreModule.ViewModels
{
    public class AddEditScoreViewModel : BindableBase, IDialogAware
    {
        private readonly HttpRestClient _httpClient;

        public AddEditScoreViewModel(HttpRestClient httpClient) 
        { 
            _httpClient = httpClient;
        }

        private ScoreDTO score;

        public ScoreDTO Score
        {
            get { return score; }
            set { SetProperty(ref score, value); }
        }

        /// <summary>
        /// 下拉框选择的学生
        /// </summary>
        private StudentDTO student;

        public StudentDTO Student
        {
            get { return student; }
            set { SetProperty(ref student, value); }
        }

        /// <summary>
        /// 学生列表
        /// </summary>
        private List<StudentDTO> students;

        public List<StudentDTO> Students
        {
            get { return students; }
            set { SetProperty(ref students, value); }
        }

        private CourseDTO course;

        public CourseDTO Course
        {
            get { return course; }
            set { SetProperty(ref course, value); }
        }

        /// <summary>
        /// 课程列表
        /// </summary>
        private List<CourseDTO> courses;

        public List<CourseDTO> Courses
        {
            get { return courses; }
            set { SetProperty(ref courses, value); }
        }

        private DelegateCommand loadedCommand;

        public DelegateCommand LoadedCommand
        {
            get
            {
                if (loadedCommand == null)
                {
                    loadedCommand = new DelegateCommand(Loaded);
                }
                return loadedCommand;
            }
        }

        private async void Loaded()
        {
            await LoadStudents();
            await LoadCourses();

            if (Score.StudentId > 0)
            {
                this.Student = Students?.FirstOrDefault(r => r.Id == Score.StudentId);
            }
            if (Score.CourseId > 0)
            { 
                this.Course = Courses?.FirstOrDefault(r=>r.Id == Score.CourseId);
            }
        }

        private DelegateCommand cancelCommand;

        public DelegateCommand CancelCommand
        {
            get
            {
                if (cancelCommand == null)
                {
                    cancelCommand = new DelegateCommand(Cancel);
                }
                return cancelCommand;
            }
        }

        private void Cancel()
        {
            RequestClose?.Invoke((new DialogResult(ButtonResult.Cancel)));
        }

        private DelegateCommand saveCommand;

        public DelegateCommand SaveCommand
        {
            get
            {
                if (saveCommand == null)
                {
                    saveCommand = new DelegateCommand(Save);
                }
                return saveCommand;
            }
        }

        private async void Save()
        {
            if (Score != null)
            {
                Score.CreateTime = DateTime.Now;
                Score.LastEditTime = DateTime.Now;
                if (Student != null)
                {
                    Score.StudentId = Student.Id;
                    Score.StudentName = Student.Name;
                }
                if (Course != null) { 
                    Score.CourseId = Course.Id;
                    Score.CourseName = Course.Name;
                }
                bool flag = false;
                if (Score.Id > 0)
                {
                    flag = await UpdateScore(Score);
                }
                else
                {
                    flag = await AddScore(Score);
                }
                if (flag)
                {
                    RequestClose?.Invoke((new DialogResult(ButtonResult.OK)));
                }
                else
                {
                    //保存失败
                }
            }
        }

        private async Task<bool> AddScore(ScoreDTO score)
        {
            ApiRequest request = new ApiRequest();
            request.Method = RestSharp.Method.Post;
            request.Parameters = score;
            request.Route = Api.SCORE_ADDSCORE;
            ResponseResultModel response = await _httpClient.Execute(request);
            if (response.code == 1)
            {
                long r = (long)response.data;
                return r == 1;
            }
            return false;
        }

        private async Task<bool> UpdateScore(ScoreDTO score)
        {
            ApiRequest request = new ApiRequest();
            request.Method = RestSharp.Method.Put;
            request.Parameters = score;
            request.Route = Api.SCORE_UPDATESCORE;
            ResponseResultModel response = await _httpClient.Execute(request);
            if (response.code == 1)
            {
                long r = (long)response.data;
                return r == 1;
            }
            return false;
        }

        private async Task LoadStudents()
        {
            this.Students = new List<StudentDTO>();
            var pagingModel = await GetStudents(null, null, 1, -1);
            if (pagingModel != null)
            {
                var entities = pagingModel.Items;
                Students.AddRange(entities);
            }
        }

        private async Task<PagingModel<StudentDTO>?> GetStudents(string? no, string? name, int pageNum, int pageSize)
        {
            Dictionary<string, object> parameters = new Dictionary<string, object>();
            parameters["no"] = no;
            parameters["name"] = name;
            parameters["pageNum"] = pageNum;
            parameters["pageSize"] = pageSize;

            ApiRequest request = new ApiRequest();
            request.Method = RestSharp.Method.Get;
            request.Parameters = parameters;
            request.Route = Api.STUDENT_GETSTUDENTS;
            ResponseResultModel response = await _httpClient.Execute(request);
            if (response.code == 1)
            {
                var students = JsonConvert.DeserializeObject<PagingModel<StudentDTO>>(JsonConvert.SerializeObject(response.data));
                return students;
            }
            return null;
        }

        /// <summary>
        /// 加载课程列表
        /// </summary>
        private async Task LoadCourses() {
            this.Courses = new List<CourseDTO>();
            var pagingModel = await GetCourses(null, null, 1, -1);
            if (pagingModel != null)
            {
                var entities = pagingModel.Items;
                Courses.AddRange(entities);
            }
        }

        private async Task<PagingModel<CourseDTO>?> GetCourses(string? courseName, string? teacher, int pageNum, int pageSize)
        {
            Dictionary<string, object> parameters = new Dictionary<string, object>();
            parameters["courseName"] = courseName;
            parameters["teacher"] = teacher;
            parameters["pageNum"] = pageNum;
            parameters["pageSize"] = pageSize;

            ApiRequest request = new ApiRequest();
            request.Method = RestSharp.Method.Get;
            request.Parameters = parameters;
            request.Route = Api.COURSE_GETCOURSES;
            ResponseResultModel response = await _httpClient.Execute(request);
            if (response.code == 1)
            {
                var courses = JsonConvert.DeserializeObject<PagingModel<CourseDTO>>(JsonConvert.SerializeObject(response.data));
                return courses;
            }
            return null;
        }

        public string Title => "新增或编辑成绩窗口";

        public event Action<IDialogResult> RequestClose;

        public bool CanCloseDialog()
        {
            return true;
        }

        public void OnDialogClosed()
        {
            
        }

        public void OnDialogOpened(IDialogParameters parameters)
        {
            if (parameters != null && parameters.ContainsKey("score"))
            {
                var score = parameters.GetValue<ScoreDTO>("score");
                this.Score = (ScoreDTO)score.Clone();
            }
            else
            {
                this.Score = new ScoreDTO();
            }
        }
    }
}
